package com.aries.remoteplusserver.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.Timer;
import javax.swing.border.TitledBorder;

import com.aries.remoteplusserver.core.OSCHandler;
import com.aries.remoteplusserver.util.DiscoverableThread;
import com.illposed.osc.OSCPort;


public class AppFrame extends JFrame{ 

	private JTabbedPane tabbedPane;
	
	private JPanel generalPanel;
	private JPanel connectionPanel;
	private JPanel securityPanel;
	private JPanel logPanel;
	private JPanel aboutPanel;
	
	private JButton okButton;
	private JButton cancelButton;
	private JButton applyButton;
	
	private Timer timer;
	private OSCHandler handler;
	
	private DiscoverableThread discoverableThread;
	
	/**
	 * Constructor
	 * @param width
	 * @param height
	 * @param xLocation
	 * @param yLocation
	 */
    public AppFrame(int width, int height, int xLocation, int yLocation) 
    {       
    	this.initTabPane();
    	this.initButtons();
    	
		this.add(tabbedPane);
		this.add(okButton);
		this.add(cancelButton);
		this.add(applyButton);
		
		this.setLayout(null);
		this.setSize(width, height);
		this.setResizable(false);
		this.setLocation(xLocation, yLocation);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    private void initTabPane()
    {
    	this.tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		this.tabbedPane.putClientProperty("JTabbedPane.closeButton", "left");
		
		this.initGenPanel();
		this.tabbedPane.addTab("General", generalPanel);
		
		this.initConnPanel();
		this.tabbedPane.addTab("Connection", connectionPanel);
		
		this.initSecPanel();
		this.tabbedPane.addTab("Security", securityPanel);
		
		this.initLogPanel();
		this.tabbedPane.addTab("Log  ", logPanel);
		
		this.initaboutPanel();
		this.tabbedPane.addTab("about", aboutPanel);
		
		this.tabbedPane.setBounds(10, 10, 435, 500);
    }
    
    private void initGenPanel()
    {
    	this.generalPanel = new JPanel();
    	this.generalPanel.setLayout(null);
    	
    	final JPanel statusProxyPanel = new JPanel();
    	final TitledBorder statusTitledBorder = new TitledBorder("Server Status");
    	
    	final JLabel statusLabel = new JLabel("Status:");
    	statusLabel.setBounds(15, 30, 60, 30);
    	statusProxyPanel.add(statusLabel);
    	
    	final JLabel statusValLabel = new JLabel("Started");
    	statusValLabel.setBounds(95, 30, 60, 30);
    	statusProxyPanel.add(statusValLabel);
    	
    	final JLabel uptimeLabel = new JLabel("Uptime");
    	uptimeLabel.setBounds(15, 60, 60, 30);
    	statusProxyPanel.add(uptimeLabel);
    	
    	final JLabel uptimeValLabel = new JLabel("0:00:00:00");
    	uptimeValLabel.setBounds(95, 60, 100, 30);
    	statusProxyPanel.add(uptimeValLabel);
    	
    	final JButton startButton = new JButton("Start");
    	startButton.setBounds(15, 110, 70, 25);
    	statusProxyPanel.add(startButton);
    	
    	final JButton stopButton = new JButton("Stop");
    	stopButton.setBounds(105, 110, 70, 25);
    	statusProxyPanel.add(stopButton);
    	
    	statusProxyPanel.setLayout(null);
    	statusProxyPanel.setBorder(statusTitledBorder);
    	statusProxyPanel.setBounds(10, 10, 420, 160);
    	
    	final JPanel settingProxyPanel = new JPanel();
    	final TitledBorder settingTitledBorder = new TitledBorder("Settings");
    	
    	final JCheckBox startupCheckBox = new JCheckBox("Start Server on system startup");
    	startupCheckBox.setBounds(10, 30, 230, 25);
    	settingProxyPanel.add(startupCheckBox);
    	
    	final JCheckBox welcomeCheckBox = new JCheckBox("Show welcome message when server starts");
    	welcomeCheckBox.setBounds(10, 60, 300, 25);
    	settingProxyPanel.add(welcomeCheckBox);
    	
    	settingProxyPanel.setLayout(null);
    	settingProxyPanel.setBorder(settingTitledBorder);
    	settingProxyPanel.setBounds(10, 200, 420, 160);
    	
    	this.generalPanel.add(statusProxyPanel);
    	this.generalPanel.add(settingProxyPanel);
    }
    
    private void initConnPanel()
    {
    	this.connectionPanel = new JPanel();
    	this.connectionPanel.setLayout(null);
    	
    	/*Initial TCP UI*/
    	final JPanel tcpProxyPanel = new JPanel();
    	final TitledBorder tcpTitledBorder = new TitledBorder("TCP");
    	
    	final JCheckBox tcpCheckBox = new JCheckBox("Accept TCP connections");
    	tcpCheckBox.setBounds(10, 45, 200, 25);
    	tcpProxyPanel.add(tcpCheckBox);
    	
    	final JLabel tcpPortLabel = new JLabel("Port:");
    	tcpPortLabel.setBounds(250, 45, 60, 25);
    	tcpProxyPanel.add(tcpPortLabel);
    	
		SpinnerNumberModel numberModel = new SpinnerNumberModel(57110, 3390, 65535, 1);
    	final JSpinner tcpPortSpinner = new JSpinner(numberModel);
    	tcpPortSpinner.setBounds(300, 45, 100, 30);
    	tcpProxyPanel.add(tcpPortSpinner);
    	
    	tcpProxyPanel.setLayout(null);
    	tcpProxyPanel.setBorder(tcpTitledBorder);
    	tcpProxyPanel.setBounds(10, 10, 420, 100);
    	
    	/*Initial UDP UI*/
    	final JPanel udpProxyPanel = new JPanel();
    	final TitledBorder udpTitledBorder = new TitledBorder("UDP");
    	
    	final JCheckBox udpCheckBox = new JCheckBox("Accept UDP connections");
    	udpCheckBox.setBounds(10, 45, 200, 25);
    	udpProxyPanel.add(udpCheckBox);
    	
    	final JLabel udpPortLabel = new JLabel("Port:");
    	udpPortLabel.setBounds(250, 45, 60, 25);
    	udpProxyPanel.add(udpPortLabel);
    	
    	final JSpinner udpPortSpinner = new JSpinner(numberModel);
    	udpPortSpinner.setBounds(300, 45, 100, 30);
    	udpProxyPanel.add(udpPortSpinner);
    	
    	udpProxyPanel.setLayout(null);
    	udpProxyPanel.setBorder(udpTitledBorder);
    	udpProxyPanel.setBounds(10, 150, 420, 100);
    	
    	this.connectionPanel.add(tcpProxyPanel);
    	this.connectionPanel.add(udpProxyPanel);
    	
    	this.discoverableThread = new DiscoverableThread(OSCPort.defaultSCOSCPort()+1);
    	this.discoverableThread.setUdpPort(Integer.parseInt(udpPortSpinner.getValue().toString()));
    	this.discoverableThread.start();
    }
    
    private void initSecPanel()
    {
    	this.securityPanel = new JPanel();
    	this.securityPanel.setLayout(null);
    	
    	final JPanel secProxyPanel = new JPanel();
    	final TitledBorder secTitledBorder = new TitledBorder("Password & Encryption");
    	
    	final JCheckBox pwCheckBox = new JCheckBox("Enable password protection");
    	pwCheckBox.setBounds(20, 40, 200, 25);
    	secProxyPanel.add(pwCheckBox);
    	
    	final JTextField pwTextField = new JTextField();
    	pwTextField.setBounds(50, 70, 300, 25);
    	pwTextField.setEnabled(false);
    	secProxyPanel.add(pwTextField);
    	
    	secProxyPanel.setLayout(null);
    	secProxyPanel.setBorder(secTitledBorder);
    	secProxyPanel.setBounds(10, 10, 420, 220);
    	
    	this.securityPanel.add(secProxyPanel);
    }
    
    private void initLogPanel()
    {
    	this.logPanel = new JPanel();
    }
    
    private void initaboutPanel()
    {
    	this.aboutPanel = new JPanel();
    }
    
    private void initButtons()
    {
    	this.okButton = new JButton("OK");
    	this.okButton.setBounds(160, 515, 90, 30);
    	
    	this.cancelButton = new JButton("Cancel");
    	this.cancelButton.setBounds(255, 515, 90, 30);
    	
    	this.applyButton = new JButton("Apply");
    	this.applyButton.setBounds(350, 515, 90, 30);
    }
    
    public void OSCLanucher()
    {
    	this.timer = new Timer(500, new ActionListener() {
			public void actionPerformed(ActionEvent ev) {
				handler = new OSCHandler();
				handler.onMessageIn();
				repaint();
				timer.stop();
			}
		});
		this.timer.start();
    }
}
